'use strict';
/**
 * author：小小游 --- allen
 * date：2018.02.05
 * lastUpdateDate：2018.02.05
 * description：Generator函数与yield语句的使用
 */
/**
  * 这是一个generator函数，内部它实现了Iterator接口
  * generator函数可以配合yield语句一起执行，如果没有yield语句，
  * 那么当调用next()方法的时候，就会执行完整个generator函数
  * 如果有了yield语句，它会把generator函数内部分成几段去执行，
  * 那么每一个断点是通过yield语句来暂停的
  * yield语句hereturn语句的区别就在于：yield语句可以返回多个值，
  * 而return语句每次只能返回一个值
  */
/**
 * 利用generator函数和promise来让异步这种逻辑关系用同步的方式表达出来
 * 我们知道同步的语句很好写，从上至下的执行，而在Javascript中，异步通常
 * 是通过回调的方式来实现，而这种回调的方式并不优雅，下面直接上例子，如下：
 */
// promise函数
function asyncFunc (name) {
    return new Promise ((resolve, reject) => {
        // 模拟异步执行
        setTimeout(() => {
            resolve (`my name is ${name}`);
        }, 200)
    });
}

// 做一个普通的加法函数
function sum (a, b) {
    return new Promise ((resolve, reject) => {
        setTimeout (() => {
            resolve (a + b);
        });
    });
}

// generator函数
// 那么这种异步的写法就可以通过同步语法糖的方式来编写
function * fn (name) {
    // let name = yield asyncFunc('allen');
    // console.log(name);
    let sumResult = yield sum (3, 5);
    // result：8
    console.log(sumResult);
    if (sumResult > 6 ) {
        // result：my name is xiaoxiaoyou
        console.log(yield asyncFunc (name));
    } else {
        console.log('error!');
    }
}

/**
 * print result：{ value: Promise { <pending> }, done: false } start
 */
// var iterator = fn ();
// console.log(iterator.next());
/**
 * print result：{ value: Promise { <pending> }, done: false } end
 */

// 执行generator的函数，gf就是执行generator对象返回的指针对象
let gf = fn ('xiaoxiaoyou');
function executedFunc (gf, value) {
    let iterator = gf.next(value);
    // done为false才继续往下遍历
    if (!iterator.done) {
        // 判断是否为Promise的实例对象
        // 串行化处理下
        if (iterator.value instanceof Promise) {
            iterator.value
                .then ((successVal) => {
                    executedFunc (gf, successVal);
                }, (failVal) => {
                    console.log(`${failVal}`);
                });
        } else {
            executedFunc (gf, iterator.value);
        }
    }
}

// 执行，看看效果，哈哈！
executedFunc (gf);
